<?php
namespace app\common\model;
use think\Model;
use think\facade\Cache;
use think\facade\Db;
use base\pay\WxApi;
use base\other\Strings;

/**
 * TODO 用户提现
 * Class UserExtract
 * @package app\models\user
 */
class UserExtract  extends Model
{
	
	// 自动完成
	protected $insert = ['extract_no'];
	protected function setExtractNoAttr() {
		return Strings::createOrderNo('tx');
    }
	
    //审核中
    const AUDIT_STATUS = 0;
    //未通过
    const FAIL_STATUS = -1;
    //已提现
    const SUCCESS_STATUS = 1;
	//--
    protected static $extractType = ['alipay','bank','wx'];
    protected static $extractTypeMsg = [
    	'alipay'=>'支付宝',
    	'bank'=>'银行卡',
    	'wx'=>'微信'
    ];
    protected static $status = array(
        -1=>'未通过',
        0 =>'审核中',
        1 =>'已提现'
    );
	
    /**
     * 用户自主提现记录提现记录,后台执行审核
     * @param array $userInfo 用户个人信息
     * @param array $data 提现详细信息
     * @return bool
     */
    public  function userExtract($userId,$data,$type='brokerage'){
		//获取参数
    	list($extractType,$extractPrice,$extractName,$extractCode,$bankCode,$bankName) = [
    		$data['extract_type'] ?: '',
    		$data['extract_price'] ?: 0,
    		$data['extract_name'] ?: '',
    		$data['extract_code'] ?: '',
    		$data['bank_code'] ?: '',
    		$data['bank_name'] ?: ''
    	];
		
		if(empty($extractType) || empty($extractPrice)) {
		  	throw new \think\Exception('必填参数项错误！');
        }
        if(!in_array($extractType,self::$extractType)){
        	throw new \think\Exception('提现方式不存在！');
        }
		if($extractType == 'alipay' && (empty($extractName) || empty($extractCode)) ) {
        	throw new \think\Exception('必填参数项错误！');
        }
		if($extractType == 'bank' && (empty($extractName) || empty($extractCode) || empty($bankCode))) {
        	throw new \think\Exception('必填参数项错误！');
        }
		
	
        
		$userInfo = model('user')->get($userId);
		$minWithdraw = (float)getSystem('buess_user_extract_min');
		$withdrawCost = (float)getSystem('buess_user_extract_cost');
		$accountMoney = $userInfo[$type];
        if($accountMoney < 0 || $extractPrice > $accountMoney) {
		  	throw new \think\Exception('账户余额不足'.$extractPrice);
        }
		//手续费
		$proceduresCost = ($withdrawCost / 100) * $extractPrice;
		if($extractPrice < ($minWithdraw ?? 1)) {
			throw new \think\Exception('提现金额必须大于等于 '.($minWithdraw ?: 1));
        }
	
 
        $balance = bcsub($accountMoney,$extractPrice,2);
		$balance = $balance < 0 ? 0 : $balance;
        $insertData = [
            'uid' => $userInfo['id'],
            'shop_id'=>$userInfo['shop_id'],
            'money_type' => $type,
            'extract_type' => $extractType,
            'extract_price' => $extractPrice,
            'extract_code'=>$extractCode ?: $userInfo['openid'],
            'extract_name'=> $extractName ?: $userInfo['nickname'],
            'bank_code'=>$bankCode,
            'bank_name'=>$bankName,
            'balance' => $balance,
            'procedures_price'=> $proceduresCost,
            'status' => self::AUDIT_STATUS
        ];
		
		
        if($extractType == 'alipay'){
            $mark = '使用支付宝提现'.$extractPrice.'元';
        }else if($extractType== 'bank'){
            $mark = '使用银联卡'.$insertData['extract_code'].'提现'.$extractPrice.'元';
        }else if($data['extract_type'] == 'wx'){
            $mark = '使用微信提现'.$extractPrice.'元';
        }
		
        \Db::startTrans();
        try{
            $res1 = self::create($insertData);
            if(!$res1) {
            	\Db::rollback();
            	throw new \think\Exception('提现失败！');
            }
            $res2 = model('User')->where("id",$userInfo['id'])->update([$type=>$balance]);
            $res3 = model('UserBill')->expend('佣金提现',$userInfo['id'],$type,'extract',$extractPrice,$res1['extract_no'],$balance,$mark);
            $res = $res2 && $res3;
            if(!$res){
                \Db::rollback();
				throw new \think\Exception('提现失败！');
            }
            \Db::commit();
            return	true;
        }catch (\Exception $e){
            \Db::rollback();
			throw new \think\Exception('提现失败！');
        }
    }
	
	 /**
     * 驳回
     * @param $openid
     * @return mixed
     */
    public function reject($id,$desc,$type='brokerage')
    {
        $extract = self::get($id);
		if($extract['status'] != 0){
  			throw new \think\Exception('状态错误！');
		}
		
		$uid = $extract['uid'];
		
		\Db::startTrans();
        try{
        	
        	$extract -> status_desc = $desc;
			$extract -> status_time = date("Y-m-d H:i:s");
			$extract -> status = -1;
	        if( !$extract -> save() ) {
	        	\Db::rollback();
	    		throw new \think\Exception('失败！');
	        }
		
			$extractPrice = $extract['extract_price'];
			$userBrokeragePrice = model('user')->where('id',$uid)->value($type);
			$balance = bcadd($userBrokeragePrice,$extractPrice,2);
			$type = $extract['money_type'];
			$res2 = model('User')->where("id",$uid)->update([$type=>$balance]);
			$res3 =model('UserBill')->where('link_id',$extract['extract_no'])->update(['status'=>'-1']);
        	$res4 = model('UserBill')->income('提现驳回',$uid,$type,'extract_reject',$extractPrice,$extract['extract_no'],$balance,'提现被驳回',0,'-1');
            $res = $res2 && $res3 && $res4;
            if(!$res){
                \Db::rollback();
				throw new \think\Exception('失败！');
            }
			
            \Db::commit();
            return	true;
			
        }catch (\Exception $e){
            \Db::rollback();
			throw new \think\Exception($e->getMessage());
        }
    }
	
	
	/**
     * 确认
     * @param $openid
     * @return mixed
     */
    public function confirm($id)
    {
        $extract = self::get($id);
		if($extract['status'] != 0){
  			throw new \think\Exception('状态错误！');
		}
		
		$minWithdraw = (float)getSystem('buess_user_extract_min');
		if($extract['extract_price'] < $minWithdraw){
  			throw new \think\Exception('未达到最低提现：'.$minWithdraw);
		}
		
		$uid = $extract['uid'];
		$no = $extract['extract_no'];
		$name = $extract['extract_name'];
		$price = $extract['extract_price'];
		$bankCode = $extract['bank_code'];
		$bankName = $extract['bank_name'];
		$openid = model('user')->where('id',$uid)->value('openid');
		
		\Db::startTrans();
        try{
        	
        	$extract -> status_time = date("Y-m-d H:i:s");
			$extract -> status = 1;
            $res = $extract -> save();
	        if(!$res) {
	        	\Db::rollback();
	  			throw new \think\Exception( '失败！');
	        }
			
			$isAutoWithdraw= (float)getSystem('money_brokerage_is_auto_withdraw');
			if($isAutoWithdraw!=1){
				if($extract['extract_type'] == 'wx'){
					$res = WxApi::withdrawal($openid,$no,$name,$price,'佣金提现到微信',"wx_app");
				}
				if($extract['extract_type'] == 'bank'){
					$desc = '佣金提现到银行卡';
					$res = WxApi::withdrawalBank($no,$name,$price,$bankCode,$bankName,$desc);
				}
				if($extract['extract_type'] == 'alipay'){
	  				throw new \think\Exception( '线上支付宝提现，功能未实现！');
				}
			}
	
            if(!$res){
                \Db::rollback();
	  			throw new \think\Exception('失败！');
            }
			
            \Db::commit();
            return	true;
			
        }catch (\Exception $e){
            \Db::rollback();
            throw new \think\Exception($e->getMessage());
        }
    }

    /**
     * 获得用户最后一次提现信息
     * @param $openid
     * @return mixed
     */
    public static function userLastInfo($uid)
    {
        return self::where(compact('uid'))->order('add_time DESC')->find();
    }

    /**
     * 获得用户提现总金额
     * @param $uid
     * @return mixed
     */
    public static function userExtractTotalPrice($uid)
    {
        return self::where('uid',$uid)->value('SUM(extract_price)')?:0;
    }

    /**
     * 用户提现记录列表
     * @param int $uid 用户uid
     * @param int $first 截取行数
     * @param int $limit 截取数
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function extractList($uid)
    {
        return self::alias('a')
        	->leftJoin('user b','a.uid = b.id')
        	->where('a.uid',$uid)
        	->where('a.shop_id = b.shop_id')
        	->order('a.add_time desc')
        	->page(input('pageIndex') ?: 1,input('pageSize') ?: 20)
        	->select();
    }

    /**
     * 获取累计已提现佣金
     * @param $uid
     * @return float
     */
    public static function extractSum($uid)
    {
        return self::where('uid',$uid)->where('status',1)->sum('extract_price');
    }

}